package com.ls.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.ls.base.BaseResult;
import com.ls.base.BaseResultUtil;
import com.ls.config.redis.RedisClient;
import com.ls.constant.SystemConstants;
import com.ls.controller.customer.model.AppLoginModel;
import com.ls.controller.customer.model.RegisterCustomerModel;
import com.ls.controller.customer.model.RegisterOrLoginModel;
import com.ls.controller.user.model.LoginModel;
import com.ls.exception.ErrorEnums;
//import com.ls.service.ICompanyService;
import com.ls.service.ICustomerService;
import com.ls.service.ILoginService;
import com.ls.utils.ResultData;
import com.ls.utils.VerifyCodeUtil;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @ClassName LoginController
 * @Description 登录相关接口
 * @Author pengyu
 * @Date 2019/9/14 10:19
 * @Version 1.0
 **/
@Slf4j
@Api(value = "登录相关接口", tags = "登录相关接口")
@RestController
@RequestMapping(value = "/login")
@RequiredArgsConstructor
public class LoginController {
    private final ILoginService loginService;
    private final ICustomerService customerService;
    private final RedisClient redisClient;

    /**
     * RSA公钥
     */
    @Value("${RSA.publicKey}")
    private String publicKey;


    @GetMapping(value = "/getPublicKey")
    @ResponseBody
    public BaseResult getPublicKey() {
        return BaseResultUtil.success(publicKey);
    }


    /**
     * 获取验证码图片和文本(验证码文本会保存在redis中)
     *
     * @param response
     * @return void
     */
    @GetMapping(value = "/getVerifyCodeImage")
    @ResponseBody
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        String verifyCode = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_LOWER, 4, null);
        session.removeAttribute(SystemConstants.WEB_VERIFY_CODE);
        session.setAttribute(SystemConstants.WEB_VERIFY_CODE, verifyCode);
        response.setContentType("image/jpeg");
        BufferedImage bufferedImage = VerifyCodeUtil.generateImageCode(verifyCode, 90, 30, 3, true, Color.WHITE, Color.BLACK, null);
        ImageIO.write(bufferedImage, "jpeg", response.getOutputStream());
    }

    /**
     * PC端 登录
     * */
    @PostMapping(value = "pcLogin")
    @ResponseBody
    public ResultData pcLogin(@Valid @RequestBody LoginModel loginModel, HttpServletRequest request) {
//        String sessionVerifyCode = (String) request.getSession().getAttribute(SystemConstants.WEB_VERIFY_CODE);
//        //TEST_VERFICATION_CODE 方便直接调用接口测试
//        if (!SystemConstants.TEST_VERFICATION_CODE.equals(loginModel.getVerifyCode())) {
//            if (sessionVerifyCode == null || !sessionVerifyCode.equals(loginModel.getVerifyCode().toLowerCase())) {
//                return ResultData.failure(ErrorEnums.UNDEFINED_EXCEPTION.getCode(),
//                        "验证码错误或已过期,请刷新页面重试");
//            }
//            request.getSession().removeAttribute(SystemConstants.WEB_VERIFY_CODE);
//        }
        return loginService.pcLogin(loginModel.getAccount(), loginModel.getPassword());
    }

    /** APP 获取短信验证码，5分钟有效 注册和登录都需要使用  */
    @GetMapping(value = "getSmsVerifyCode")
    public ResultData getSmsVerifyCode(@RequestParam String phone) {
        return customerService.getSmsVerifyCode(phone);
    }

    /** APP 验证码注册或登录 */
    @PostMapping(value = "appRegisterOrLogin")
    public ResultData appRegisterOrLogin(@Valid @RequestBody RegisterOrLoginModel model, HttpServletRequest request) {
        String key = model.getPhone() + "_smsVerifyCode";
        String sessionVerifyCode = (String) redisClient.getJsonString(key);
        log.info("sessionVerifyCode:{}", sessionVerifyCode);
//        String sessionVerifyCode = (String) request.getSession().getAttribute(SystemConstants.SMS_VERIFY_CODE);
        //TEST_VERFICATION_CODE 方便直接调用接口测试
        if (!SystemConstants.APP_TEST_VERFICATION_CODE.equals(model.getSmsVerifyCode())) {
            if (sessionVerifyCode == null || !sessionVerifyCode.equals(model.getSmsVerifyCode())) {
                return ResultData.failure(ErrorEnums.UNDEFINED_EXCEPTION.getCode(),
                        "验证码错误或已过期,请刷新页面重试");
            }
            request.getSession().removeAttribute(SystemConstants.SMS_VERIFY_CODE);
        }
        return customerService.appRegisterOrLogin(model);
    }

    /** APP 密码登录 */
    @PostMapping(value = "appPwdLogin")
    public ResultData appPwdLogin(@Valid @RequestBody AppLoginModel model) {
        return customerService.appPwdLogin(model);
    }

    /** 退出登录 */
    @GetMapping(value = "logout")
    @ResponseBody
    public ResultData logout(HttpServletResponse response) throws Exception {
        // 当前会话退出登录
        StpUtil.logout();
        //清除缓存
//        StpUtil.getTokenSession().logout();
        return ResultData.successMsg("退出登录成功");
    }

    /** 注销账号 */
    @PostMapping(value = "cancelAccount")
    @ResponseBody
    public ResultData cancelAccount() {
        return customerService.cancelAccount();
    }


    /**
     * 拦截登录接口，返回json，由前端判断，跳转登录页面
     */
    @RequestMapping(value = "goLogin")
    @ResponseBody
    public ResultData goLogin() {
        //清除session
        StpUtil.logout();
        return ResultData.failure(ErrorEnums.LOGIN_OUT_OF_DATE.getCode(),
                ErrorEnums.LOGIN_OUT_OF_DATE.getMessage());
    }

    /**
     * 没有权限时拦截到的接口
     */
    @GetMapping(value = "unauthorized")
    @ResponseBody
    public ResultData unauthorized() {
        return ResultData.failure(ErrorEnums.NO_PERMISSION.getCode(),
                ErrorEnums.NO_PERMISSION.getMessage());
    }

}
